package bean.managed;

import entity.ExpectedYearOnYearGrowthEntity;
import bean.managed.util.JsfUtil;
import bean.managed.util.PaginationHelper;
import bean.session.ExpectedYearOnYearGrowthEntityFacade;

import entity.DataObjectEntity;
import entity.DepartmentEntity;
import entity.MarketSalesReportEntity;
import entity.ProductPercentageQuantityEntity;
import entity.SalesForecastEntity;
import entity.SystemUserEntity;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import javax.faces.validator.ValidatorException;
import javax.persistence.criteria.CriteriaBuilder;
import managedbean.AbstractBacking;
import org.primefaces.component.chart.series.ChartSeries;
import org.primefaces.model.chart.CartesianChartModel;
import type.MarketSalesType;
import type.Month;
import type.SalesForecastPeriodType;
import util.Fixtures.Department;


@ManagedBean (name="expectedYearOnYearGrowthEntityController")
@SessionScoped
public class ExpectedYearOnYearGrowthEntityController extends AbstractBacking implements Serializable {

    private int validateYear; //for validation
    private ExpectedYearOnYearGrowthEntity current;
    private DataModel items = null;
    @EJB private bean.session.ExpectedYearOnYearGrowthEntityFacade ejbFacade;
    private PaginationHelper pagination;
    private int selectedItemIndex;
    private Collection<MarketSalesReportEntity> marketSalesReports = new ArrayList<MarketSalesReportEntity>();
    private MarketSalesReportEntity currentMarketReport;
//     private List<MarketTrend> trends; 
    private CartesianChartModel marketTrends;;
    
     @ManagedProperty(value = "#{systemMessageController}")
    private SystemMessageController systemMessageController;
    
    
    @EJB private bean.session.SalesForecastEntityFacade forecastFacade;
    @EJB private bean.session.ProductPercentageQuantityEntityFacade ppqFacade;
    @EJB private bean.session.DepartmentEntityFacade departmentFacade;
    @EJB private bean.session.MarketSalesReportEntityFacade marketSalesFacade; //marketSalesReport
    
   

    public ExpectedYearOnYearGrowthEntityController() {
    }
    
    public CartesianChartModel getMarketTrends(){
        marketTrends = new CartesianChartModel();
        
        Calendar now = Calendar.getInstance();
        int year = now.get(Calendar.YEAR);
//        System.out.println("Year is "+ year);
        ArrayList<MarketSalesReportEntity> nutsMktSalesReport = getFacade().findMaketSalesReport(MarketSalesType.Nuts,year);
        ArrayList<MarketSalesReportEntity> fruitsMktSalesReport = getFacade().findMaketSalesReport(MarketSalesType.Fruits,year);
        
        ChartSeries nuts = new ChartSeries();  
        nuts.setLabel("Market Nuts Bar Sales");  
        for(MarketSalesReportEntity r:nutsMktSalesReport){
            nuts.set(Integer.toString(r.getYear()), r.getSalesValue());
        }
          
  
        ChartSeries fruits = new ChartSeries();  
        fruits.setLabel("Market Fruits Bar Sales");
         for(MarketSalesReportEntity r:fruitsMktSalesReport){
            fruits.set(Integer.toString(r.getYear()), r.getSalesValue());
        }
  
        
        marketTrends.addSeries(nuts);  
       marketTrends.addSeries(fruits);  
       
       return marketTrends;
        
    }
    
    public void setCurrentReport(MarketSalesReportEntity report){
        currentMarketReport = report;
    }
    
    public MarketSalesReportEntity getCurrentReport(){
        return currentMarketReport;
    }
    
    public Collection<MarketSalesReportEntity> getMarketSalesReports(){
        marketSalesReports = marketSalesFacade.findAll();
        return marketSalesReports;
    }
    
    public void setMarketSalesReport(Collection<MarketSalesReportEntity> reports){
        this.marketSalesReports = reports;
    }
    
//    public List<MarketTrend> getMarketTrends(){
//        trends = new ArrayList<MarketTrend>();
//            
//        trends.add(new MarketTrend(2006, 2880, 3000));
//        trends.add(new MarketTrend(2007, 3120, 3300));
//        trends.add(new MarketTrend(2008, 3280, 3200));
//        trends.add(new MarketTrend(2009, 3580, 3500));
//        trends.add(new MarketTrend(2010, 3880, 3725));
//        
//        return trends;
//    }
    
    public void setValidateYear(int year){
        validateYear = year;
    }
   
    public int getValidateYear(){
        return validateYear;
    }
    public void validateExistence(FacesContext context, UIComponent validate, Object value) {
//        System.out.println("current year "+current.getYearOfSales());
        SalesForecastPeriodType period = (SalesForecastPeriodType) value;
        if (ejbFacade.checkExistence(period,validateYear)) {
//            System.out.println("Should Print error message");
//            FacesMessage message = new FacesMessage();
//            message.setDetail("Sales Forecast exists");
//            message.setSummary("Sales Forecast exists");
//            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            String msg = "Sales Forecast exists";
            throw new ValidatorException(new FacesMessage(msg));
//            throw new ValidatorException(message);
        }
    }

    public ExpectedYearOnYearGrowthEntity getSelected() {
        if (current == null) {
            current = new ExpectedYearOnYearGrowthEntity();
            selectedItemIndex = -1;
        }
        return current;
    }
    
     public SystemMessageController getSystemMessageController() {
        return systemMessageController;
    }

    public void setSystemMessageController(SystemMessageController systemMessageController) {
        this.systemMessageController = systemMessageController;
    }
    

    private ExpectedYearOnYearGrowthEntityFacade getFacade() {
        return ejbFacade;
    }
    
    public PaginationHelper getPagination() {
        if (pagination == null) {
            pagination = new PaginationHelper(10) {

                @Override
                public int getItemsCount() {
                    return getFacade().count();
                }

                @Override
                public DataModel createPageDataModel() {
                    return new ListDataModel(getFacade().findRange(new int[]{getPageFirstItem(), getPageFirstItem()+getPageSize()}));
                }
            };
        }
        return pagination;
    }
    
     public SalesForecastPeriodType[] getForecastPeriodType() {
        return SalesForecastPeriodType.values();
    }
     
       public MarketSalesType[] getMarketSalesType() {
        return MarketSalesType.values();
    }
    

    public String prepareList() {
        recreateModel();
        return "/entities/salesForecastEntity/List?faces-redirect=true";
    }
    
     public String prepareListMarketSalesReport() {
        recreateModel();
        return "/entities/marketSalesReportEntity/List?faces-redirect=true";
    }        

    public String prepareView() {
        current = (ExpectedYearOnYearGrowthEntity)getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        
        return "/entities/salesForecastEntity/View?faces-redirect=true";
    }

    public String prepareCreate() {
        current = new ExpectedYearOnYearGrowthEntity();
        selectedItemIndex = -1;
        return "/entities/ExpectedYearOnYearGrowthEntity/Create?faces-redirect=true";
    }
    
     public String prepareCreateMarketReport() {
        currentMarketReport = new MarketSalesReportEntity();
//        selectedItemIndex = -1;
        return "Create";
        
    }
     
     public String createMarketSalesReport(){
         currentMarketReport.created(getLoginPerson());
         marketSalesFacade.create(currentMarketReport);
        
        try{ 
         JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("MarketSalesReportEntityCreated"));
           return "List";
        }
         catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
         
     }
     

    public String create() {
       
            
            System.out.println("creation current.year "+ current.getYearOfSales());
            
            if (ejbFacade.checkExistence(current.getForecastPeriodType(),current.getYearOfSales())) {
//            System.out.println("Should Print error message");
            FacesMessage message = new FacesMessage();
            message.setDetail("Sales Forecast exists");
            message.setSummary("Sales Forecast exists");
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            String msg = "Sales Forecast exists";
            throw new ValidatorException(new FacesMessage(msg));
//            throw new ValidatorException(message);
        }
            
          try {   
            current.created(getLoginPerson());
            
            current.setSalesForecast(forecastFacade.createLongTerm(current));
            
            Collection collection = current.getSalesForecast();
            Iterator iterator = collection.iterator();
            while(iterator.hasNext()){
                
                SalesForecastEntity element = (SalesForecastEntity) iterator.next();
                
                Collection ppqs = element.getHistoricalPPQ();
                Iterator iterator2 = ppqs.iterator();
                while(iterator2.hasNext()){
                    ProductPercentageQuantityEntity p = (ProductPercentageQuantityEntity) iterator2.next();
                    p.created(getLoginPerson());
                }
                
                element.created(getLoginPerson());
            }
            
            getFacade().create(current);
            //inform production manager
            DepartmentEntity productionDp = departmentFacade.findDepartmentByName(Department.ProductionPlanning.getName());
            SystemUserEntity productionManager = productionDp.getManager();
            String message = "Sales Forecast for Year " + current.getYearOfSales()+" ("+current.getForecastPeriodType()+") is created"; 
               
        systemMessageController.getEjbFacade().createAndSendSystemMessage(productionManager,
                        message, "/entities/salesForecastEntity/List.xhtml", systemMessageController);
            
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ExpectedYearOnYearGrowthEntityCreated"));
           recreateModel();
           return"";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }
    
    

    public String prepareEdit() {
        current = (ExpectedYearOnYearGrowthEntity)getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "Edit";
    }
    
    public String prepareEditMarketReport(MarketSalesReportEntity report) {
        currentMarketReport = report;
        
        return "Edit";
    }
    
   
    

    public String update() {
        try {
            getFacade().edit(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ExpectedYearOnYearGrowthEntityUpdated"));
            return "View";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }
    
    public String updateMarketReport() {
        try {
            currentMarketReport.modified(getLoginPerson());
            marketSalesFacade.edit(currentMarketReport);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("MarketSalesReportEntityUpdated"));
            return "List";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String destroy() {
        current = (ExpectedYearOnYearGrowthEntity)getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        performDestroy();
        recreateModel();
        return "List";
    }
    
    public String destroyMarketReport(MarketSalesReportEntity report) {
        currentMarketReport = report;
        
        currentMarketReport.modified(getLoginPerson());
        currentMarketReport.setArchived(true);
        marketSalesFacade.edit(currentMarketReport);
        recreateModel();
       
        
         try{ 
         JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("MarketSalesReportEntityDeleted"));
           return "List";
        }
         catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String destroyAndView() {
        performDestroy();
        recreateModel();
        updateCurrentItem();
        if (selectedItemIndex >= 0) {
            return "View";
        } else {
            // all items were removed - go back to list
            recreateModel();
            return "List";
        }
    }

    private void performDestroy() {
        try {
            current.setArchived(true);
            current.modified(getLoginPerson());
            archiveSalesForecast(current.getSalesForecast());
            getFacade().edit(current);;
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ExpectedYearOnYearGrowthEntityDeleted"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
        }
    }

    private void updateCurrentItem() {
        int count = getFacade().count();
        if (selectedItemIndex >= count) {
            // selected index cannot be bigger than number of items:
            selectedItemIndex = count-1;
            // go to previous page if last page disappeared:
            if (pagination.getPageFirstItem() >= count) {
                pagination.previousPage();
            }
        }
        if (selectedItemIndex >= 0) {
            current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex+1}).get(0);
        }
    }

    public DataModel getItems() {
        if (items == null) {
            items = getPagination().createPageDataModel();
        }
        return items;
    }

    private void recreateModel() {
        items = null;
        current = null;
        currentMarketReport = null;
        validateYear = 0;
    }

    public String next() {
        getPagination().nextPage();
        recreateModel();
        return "List";
    }

    public String previous() {
        getPagination().previousPage();
        recreateModel();
        return "List";
    }

    public SelectItem[] getItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
    }

    public SelectItem[] getItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
    }
    
       public String resetCreate() {
        recreateModel();
        return "/entities/ExpectedYearOnYearGrowthEntity/Create?faces-redirect=true";
    }

    public void archiveSalesForecast(Collection<SalesForecastEntity> salesForecast) {
        Iterator iterator = salesForecast.iterator();
        while(iterator.hasNext()){
            SalesForecastEntity sales = (SalesForecastEntity)iterator.next();
            sales.modified(getLoginPerson());
            archivePPQ(sales);
            forecastFacade.remove(sales);
        }

    }

    public void archivePPQ(SalesForecastEntity sales) {
      Collection<ProductPercentageQuantityEntity> ppqs = sales.getHistoricalPPQ();
      Iterator iterator = ppqs.iterator();
        while(iterator.hasNext()){
            ProductPercentageQuantityEntity ppq = (ProductPercentageQuantityEntity)iterator.next();
            ppq.modified(getLoginPerson());
            ppqFacade.remove(ppq);
            
        }
    }
           public int[] getYear(){
int a = 2003;
int[] d = new int[40];
for(int i = 0;i<40;i++){
d[i]=a++;

}
return d;
}
     
      
       

    @FacesConverter(forClass=ExpectedYearOnYearGrowthEntity.class)
    public static class ExpectedYearOnYearGrowthEntityControllerConverter implements Converter {

        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            ExpectedYearOnYearGrowthEntityController controller = (ExpectedYearOnYearGrowthEntityController)facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "expectedYearOnYearGrowthEntityController");
            return controller.ejbFacade.find(getKey(value));
        }

        java.lang.Long getKey(String value) {
            java.lang.Long key;
            key = Long.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Long value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof ExpectedYearOnYearGrowthEntity) {
                ExpectedYearOnYearGrowthEntity o = (ExpectedYearOnYearGrowthEntity) object;
                return getStringKey(o.getId());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: "+ExpectedYearOnYearGrowthEntityController.class.getName());
            }
        }
        
      

    }

}
